发票 OCR 实战:10 个常见错误及解决方案

大家好,我是正在实战各种 AI 项目的程序员晚枫。


😭 这些错误你肯定遇到过

3 个月来,处理了 10 万 + 张发票。

踩过的坑,比你吃过的盐都多。

今天:总结 10 个最常见错误及解决方案。


错误 1:密钥失效

报错AuthenticationError: Invalid credentials

原因

  • 密钥过期
  • 密钥被冻结
  • 密钥配置错误

解决

1
2
3
4
5
6
7
8
9
# 1. 检查环境变量
import os
print(os.getenv('TENCENT_SECRET_ID'))

# 2. 重新获取密钥
# 访问:https://curl.qcloud.com/9ExTmaya

# 3. 更新配置
os.environ['TENCENT_SECRET_ID'] = '新密钥'

错误 2:网络超时

报错TimeoutError: Request timeout

原因

  • 网络不稳定
  • API 响应慢
  • 防火墙限制

解决

1
2
3
4
5
6
7
8
9
10
# 添加重试机制
def recognize_with_retry(file_path, max_retries=3):
for i in range(max_retries):
try:
return poocr.ocr2excel.VatInvoiceOCR2Excel(...)
except TimeoutError:
if i < max_retries - 1:
time.sleep(5)
else:
raise

错误 3:图片格式不支持

报错ValueError: Unsupported image format

原因

  • 图片格式不在支持列表
  • 文件扩展名错误

解决

1
2
3
4
5
6
7
8
9
# 检查并转换格式
from PIL import Image

def convert_image(image_path):
img = Image.open(image_path)
if img.format not in ['JPEG', 'PNG', 'PDF']:
img = img.convert('RGB')
img.save(image_path + '.jpg', 'JPEG')
return image_path + '.jpg'

错误 4:图片太大

报错FileSizeExceeded: Image too large

原因:图片超过 API 限制(通常 10MB)

解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 压缩图片
from PIL import Image

def compress_image(image_path, max_size=5):
img = Image.open(image_path)

# 检查文件大小
file_size = os.path.getsize(image_path) / 1024 / 1024

if file_size > max_size:
# 压缩
img.save(image_path, quality=80, optimize=True)

return image_path

错误 5:识别结果为空

报错:无报错,但返回空结果

原因

  • 图片太模糊
  • 发票不在画面内
  • 光线太暗

解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 添加质量检查
def check_image_quality(image_path):
img = cv2.imread(image_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 检查亮度
if np.mean(gray) < 80:
return False, "图片太暗"

# 检查清晰度
if cv2.Laplacian(gray, cv2.CV_64F).var() < 100:
return False, "图片模糊"

return True, "合格"

错误 6:字段缺失

报错KeyError: '发票代码'

原因:OCR 识别失败,字段不存在

解决

1
2
3
4
# 安全获取字段
invoice_code = invoice_data.get('发票代码', '')
if not invoice_code:
print("⚠️ 发票代码识别失败,需要人工复核")

错误 7:Excel 写入失败

报错PermissionError: File is in use

原因:Excel 文件被占用

解决

1
2
3
4
5
6
7
8
9
10
11
12
# 检查文件是否被占用
def is_file_in_use(file_path):
try:
with open(file_path, 'r+') as f:
pass
return False
except PermissionError:
return True

# 等待文件释放
while is_file_in_use(output_path):
time.sleep(1)

错误 8:编码错误

报错UnicodeDecodeError: 'gbk' codec can't decode

原因:文件编码问题

解决

1
2
3
4
5
6
7
8
9
10
11
12
# 指定编码
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()

# 或尝试多种编码
for encoding in ['utf-8', 'gbk', 'gb2312']:
try:
with open(file_path, 'r', encoding=encoding) as f:
content = f.read()
break
except:
continue

错误 9:路径错误

报错FileNotFoundError: No such file or directory

原因:路径不存在或拼写错误

解决

1
2
3
4
5
6
7
# 使用绝对路径
import os
abs_path = os.path.abspath(file_path)

# 检查路径是否存在
if not os.path.exists(abs_path):
print(f"❌ 文件不存在:{abs_path}")

错误 10:API 额度超限

报错QuotaExceeded: Monthly quota exceeded

原因:超出免费额度

解决

1
2
3
4
5
6
7
8
9
10
11
# 检查剩余额度
def check_quota():
response = requests.get(
'https://console.cloud.tencent.com/ocr/quota',
headers={'Authorization': get_auth_token()}
)
quota = response.json()
print(f"剩余额度:{quota['remaining']}")

if quota['remaining'] < 100:
print("⚠️ 额度不足,请充值")

📊 错误处理最佳实践

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def robust_invoice_recognition(file_path):
"""健壮的发票识别"""
try:
# 1. 检查文件
if not os.path.exists(file_path):
return None, "文件不存在"

# 2. 检查质量
is_ok, msg = check_image_quality(file_path)
if not is_ok:
return None, msg

# 3. 识别
result = poocr.ocr2excel.VatInvoiceOCR2Excel(...)

# 4. 验证结果
if not result.get('发票代码'):
return None, "识别失败"

return result, "成功"

except Exception as e:
return None, f"异常:{str(e)}"

💬 联系我

平台账号/链接
微信扫码加好友
微博@程序员晚枫
知乎@程序员晚枫
抖音@程序员晚枫
小红书@程序员晚枫
B 站Python 自动化办公社区

主营业务:AI 编程培训、企业内训、技术咨询


🎓 推荐课程


错误不可怕,可怕的是不知道如何解决。

这份指南,希望能帮你少踩坑。

遇到问题,别慌,按上面的方法试试。💪

🎓 AI 编程实战课程

想系统学习 AI 编程?程序员晚枫的 AI 编程实战课 帮你从零上手!